﻿#include "loop.h"
#include "netif.h"
#include "debug.h"

static net_err_t loop_open(netif_t *netif, void *data)
{
    netif->type = NETIF_TYPE_LOOP;
    return NET_ERR_OK;
}

static net_err_t loop_close(netif_t *netif)
{
    return NET_ERR_OK;
}

static net_err_t loop_xmit(netif_t *netif)
{
    pktbuf_t *buf = netif_get_out(netif, DELIVER_NO_WAITTIME);
    // 环回网络接口是用于自发自收的
    if (buf)
    {
        net_err_t err = netif_put_in(netif, buf, DELIVER_NO_WAITTIME);
        if (err < 0)
        {
            DBG_INFO(DBG_LOOP_LEVEL, "netif:%s put message in inq failed!", netif->name);
            pktbuf_free(buf);
            return NET_ERR_DELIVER;
        }
    }
    return NET_ERR_OK;
}

static const netif_ops_t loop_ops = {
    .open = loop_open,
    .close = loop_close,
    .xmit = loop_xmit};

/**
 * @brief 环回网络接口初始化
 */
net_err_t loop_init()
{
    DBG_INFO(DBG_LOOP_LEVEL, "open loop netif!");

    netif_t *loop_netif = netif_open("loop", &loop_ops, NULL);
    if (!loop_netif)
    {
        DBG_ERROR(DBG_LOOP_LEVEL, "open loop netif failed!");
        return NET_ERR_SYS;
    }

    ipaddr_t ip, mask;
    ipaddr_from_str(&ip, LOOP_IPADDR);
    ipaddr_from_str(&mask, LOOP_MASK);
    netif_set_addr(loop_netif, &ip, &mask, NULL);

    netif_set_active(loop_netif);

    return NET_ERR_OK;
}